#include "SAW.h"

#include <cstring>

SAW::SAW(unsigned long* stepsizes, size_t amountstepsizes, unsigned int seed) {
    this->directions = 4;
    this->stepsizes = stepsizes;
    this->amountstepsizes = amountstepsizes;
    this->possibleDirections = new bool[directions];
    srand(seed);
}

unsigned long SAW::newstepsize() {
    unsigned long result = stepsizes[stepsizeCounter];
    stepsizeCounter = (stepsizeCounter + 1) % amountstepsizes;
    return result;
}

unsigned long SAW::walk() {
    stepsizeCounter = 0;
    stepsize = newstepsize();
    Point point = startPoint;
    add(point);
    unsigned long steps = 0;

    unsigned long direction;
    unsigned long directions = calculatePossibleDirections(point);
    while (directions != 0) {
        direction = getDirection((rand() % directions));

        if (direction == 0) {
        	add(Point{point.x, point.y + stepsize});
        } else if (direction == 1) {
        	add(Point{point.x + stepsize, point.y});
        } else if (direction == 2) {
            add(Point{point.x, point.y - stepsize});
        } else if (direction == 3) {
        	add({point.x - stepsize, point.y});
        }

        ++steps;
        directions = calculatePossibleDirections(point);
    }
    return steps;
}

bool SAW::checkIntersection(deque<Point> l){
	for(size_t i=0; i<l.size(); ++i){
		if(l.at(i).isLeft()){
			insert(t, s);
			if(bla || bla){
				return true;
			}
		} else {
			if(bla && bla && bla){
				return true;
			}
			delete(t,s);
		}
	}
	return false;
}

bool SAW::canGoNord(Point point) {
	deque<Point>::iterator index = lower_bound(list.begin(), list.end(), point);
	list.insert(point, index)
	checkIntersection(list);
	list.erase(index);
}

bool SAW::canGoEast(Point point) {
	deque<Point>::iterator index = lower_bound(list.begin(), list.end(), point);
	list.insert(point, index)
	checkIntersection(list);
	list.erase(index);
}

bool SAW::canGoSouth(Point point) {
	deque<Point>::iterator index = lower_bound(list.begin(), list.end(), point);
	list.insert(point, index)
	checkIntersection(list);
	list.erase(index);
}

bool SAW::canGoWest(Point point) {
	deque<Point>::iterator index = lower_bound(list.begin(), list.end(), point);
	list.insert(point, index)
	checkIntersection(list);
	list.erase(index);
}

unsigned long SAW::calculatePossibleDirections(Point point) {
    unsigned long counter = 0;

    possibleDirections[0] = canGoNord(point);
    possibleDirections[1] = canGoEast(point);
    possibleDirections[2] = canGoSouth(point);
    possibleDirections[3] = canGoWest(point);

    for (long i = 0; i < directions; ++i) {
        if (possibleDirections[i]) {
            ++counter;
        }
    }

    return counter;
}

unsigned long SAW::getDirection(unsigned int number) {
    size_t counter = 0;

    for (size_t i = 0; i < directions; ++i) {
        if (number == counter && possibleDirections[i]) {
            return i;
        }
        if (possibleDirections[i]) {
            ++counter;
        }
    }
}
